package org.zjvis.datascience.common.graph.exporter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.zjvis.datascience.common.graph.util.GraphUtil;
import org.zjvis.datascience.common.vo.graph.LinkVO;
import org.zjvis.datascience.common.vo.graph.NodeVO;

import java.io.IOException;
import java.util.Iterator;

/**
 * @description ExporterJSON
 * @date 2021-12-29
 */
public class ExporterJSON extends Exporter {
    JSONObject newJSON;
    JSONArray nodeArray;
    JSONArray linkArray;

    public ExporterJSON() {
        newJSON = new JSONObject();
        nodeArray = new JSONArray();
        linkArray = new JSONArray();
    }

    public boolean execute() {
        boolean ret = true;
        try {
            exportData();
        } catch (IOException e) {
            logger.warn("" + e.getMessage());
            ret = false;
        }
        return ret;
    }

    private void exportData() throws IOException{
        Iterator<NodeVO> nodeIter = nodes.iterator();
        while (nodeIter.hasNext()) {
            NodeVO node = nodeIter.next();
            exportNode(node);
        }

        Iterator<LinkVO> linkIter = links.iterator();
        while (linkIter.hasNext()) {
            LinkVO link = linkIter.next();
            exportLink(link);
        }

        newJSON.put("nodes", nodeArray);
        newJSON.put("links", linkArray);
    }

    private void exportNode(NodeVO node) {
        JSONObject nodeObj = new JSONObject();
        nodeObj.put("id", node.getOrderId());
        String categoryId = labelMap == null ? GraphUtil.removeAliasId(node.getCategoryId(), graphId) : labelMap.get(node.getCategoryId());
        nodeObj.put("categoryId", categoryId);
        nodeObj.put("label", node.getLabel());
        JSONObject attributes = new JSONObject();
        Exporter.makeAttributes(node.getAttrs(), attributes, node.getId(), node.getCategoryId(), multiValueHelper, metricResults);
        nodeObj.put("attributes", attributes);
        JSONObject config = new JSONObject();
        config.put("style", node.getStyle());
        config.put("labelCfg", node.getLabelCfg());
        config.put("type", node.getType());
        config.put("x", node.getX());
        config.put("y", node.getY());
        config.put("size", node.getSize());
        nodeObj.put("config", config);
        nodeArray.add(nodeObj);
    }

    private void exportLink(LinkVO link) {
        JSONObject linkObj = new JSONObject();
        linkObj.put("id", link.getOrderId());
        linkObj.put("source", Long.parseLong(GraphUtil.removeAliasId(link.getSource(), graphId)));
        linkObj.put("target", Long.parseLong(GraphUtil.removeAliasId(link.getTarget(), graphId)));
        linkObj.put("label", link.getLabel());
        linkObj.put("directed", link.getDirected());
        linkObj.put("weight", link.getWeight());
        JSONObject attributes = new JSONObject();
        Exporter.makeAttributes(link.getAttrs(), attributes, link.getId(), link.getEdgeId(), multiValueHelper, null);
        linkObj.put("attributes", attributes);
        JSONObject config = new JSONObject();
        config.put("style", link.getStyle());
        config.put("labelCfg", link.getLabelCfg());
        config.put("type", link.getType());
        config.put("controlPoints", link.getControlPoints());
        config.put("curveOffset", link.getCurveOffset());
        linkObj.put("config", config);
        linkArray.add(linkObj);
    }

    public String getJSONString() {
        return JSON.toJSONString(newJSON, SerializerFeature.PrettyFormat);
    }
}
